home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvidjc / dvidjc.c < prev    next >
C/C++ Source or Header  |  1994-02-23  |  37KB  |  995 lines

  1. /* (C)opyright 1994 Wolfgang R. Mueller, Computing Centre,
  2. Heinrich-Heine-University Duesseldorf, Germany,
  3. wolfgang@uni-duesseldorf.de, +49-211-311-3905.
  4. This program may be used without any warranty under
  5. the terms of the GNU general public licence. */
  6. /* translated from the original TurboPascal source
  7. partly with p2c, the Pascal-to-C translator */
  8.  
  9. #undef DJCOLOUR
  10. #ifdef DJ550C
  11. #define DJCOLOUR
  12. #endif
  13. #ifdef DJ500C
  14. #define DJCOLOUR
  15. #endif
  16.  
  17. #define DINA4
  18. #include <stdio.h>
  19.  
  20. #ifdef __MSDOS__
  21.  #ifdef __TURBOC__
  22.   #include <dos.h>
  23.  #else
  24.   #include <pc.h>
  25.  #endif
  26. #endif
  27.  
  28. #ifdef __TURBOC__
  29.   #include <mem.h>
  30.   #include <alloc.h>
  31.   #define malloc farmalloc
  32.   #define calloc farcalloc
  33.   #define realloc farrealloc
  34.   #define free farfree
  35. #endif
  36.  
  37. #define uchar unsigned char
  38. #define ushort unsigned short
  39. #define ulong unsigned long
  40. #define ptr void *
  41.  
  42. #define xmb       294   /* 8.5 inch X 300 dpi / 8 dot per byte*/
  43. #ifdef __TURBOC__
  44. #define ymax       47   /* +1=multiple of 8 */
  45. #else
  46. #define ymax      839   /* +1=multiple of 8 */
  47. #endif
  48. #define linl      299   /* =xmb+2+(xmb+128)div 128 */
  49. #define maxink     16
  50. #define smax      100
  51.  
  52. #ifdef __MSDOS__
  53. static char tfmprefix[] = "c:\\tex\\fonts\\tfm\\";
  54. static char fontprefix[] = "c:\\tex\\fonts\\canon\\";
  55. #else
  56. static char tfmprefix[] = "/usr/TeX/lib/tex/fonts/";
  57. static char fontprefix[] = "/usr/TeX/lib/tex/fonts/";
  58. #endif
  59.  
  60. typedef struct colpix { uchar cpix, mpix, ypix, kpix; } colpix;
  61. typedef struct greydesc { uchar maskc, maskm, masky, maskk; } greydesc;
  62.  
  63. static uchar maskmat[5][4][4] = {
  64.   { {17,2,5,17},{17,17,8,17},{17,17,17,11},{17,17,14,17} },
  65.   { {1,17,17,3},{5,17,17,6},{8,10,12,17},{14,16,17,17} },
  66.   { {17,17,17,17},{17,4,17,17},{17,17,17,17},{17,17,17,12} },
  67.   { {14,4,16,2},{7,9,5,11},{15,1,13,3},{6,12,8,10} },
  68.   { {0x88,0x44,0x22,0x11},{0,0,0,0},{0,0,0,0},{0,0,0,0} } };
  69.  
  70. static FILE *prot=stderr;
  71. static uchar stackcy[smax], stackma[smax], stackye[smax], stackbl[smax];
  72. static char STR[99], FOPRE[99], FOMAG[16], FONAM[99], FOLOC[99], FOFUL[99];
  73. static char prfnam[99] = "prn";
  74. static char defnam[73];
  75. static colpix *pxlmem[ymax + 1];
  76. static greydesc greymask[8];
  77. static uchar maskb[maxink + 1][4][4];
  78.  
  79. static uchar zoll, zoll0, vsk1, vsk2, hsk3, prfilout, clearing, prinit = 0;
  80. static long zoelli;
  81. static short zilli, lz, colst, xres, yres, xmax;
  82. static short vskop, hsk1, hsk2, lzd, vchd, prbs, prbe;
  83. static FILE *prfile;
  84. static uchar prbuf[2048];
  85.  
  86. static void Tptr(void *p) {  if(p==NULL) {
  87.   fprintf(prot, " - not enough memory :-( "); exit(1);
  88. } }
  89. static void prfeval() {
  90.   if (!strcmp(".dvi", defnam+strlen(defnam)-4)) defnam[strlen(defnam)-4]=0;
  91.   if (*prfnam == '\0')  sprintf(prfnam, "%s.pcl", defnam);
  92.   prfilout = (strcmp(prfnam, "prn") != 0);
  93.   xres = 300;  yres = 300;  xmax = xmb * 8 + 7;
  94.   zoll0 = (yres * 12 + ymax) / (ymax + 1);
  95.   if (prfilout)  fprintf(prot, "writing to file %s\n", prfnam);
  96. }
  97. static void propen() { if (prinit)  return;  prinit = 1;
  98.   prbs=0;  prbe=0;  if(prfilout)  prfile = fopen(prfnam, "w+b");
  99. }
  100. static void prflush() { if(prbs>=prbe) return;
  101.   if(prfilout) fwrite(&prbuf[prbs], prbe - prbs, 1, prfile);
  102.   prbe=0; prbs=prbe;
  103. }
  104. static void put(x) uchar x; {
  105.   if (prfilout) {
  106.     if (prbe == 2048)  prflush();
  107.     prbuf[prbe] = x;  prbe++;
  108.   } else
  109. #ifdef __MSDOS__
  110.   outportb(0x378,x);
  111.   while((inportb(0x379)&0x80)==0);
  112.   outportb(0x37a,13);
  113.   inportb(0x379);
  114.   outportb(0x37a,12);
  115. #else
  116.   putc(x,stdout);
  117. #endif
  118. }
  119. static void esc(s)  char *s;  {  short i, l;
  120.   put(0x1b);  l = strlen(s);
  121.   for (i = 0; i < l; i++)  put(s[i]);
  122. }
  123. static void prclos()  {
  124.   if (!prinit)  return;
  125.   prflush();  prinit = 0;
  126.   if (prfilout)  fclose(prfile);
  127. }
  128. static void hardform()  {  esc("*rbC");  put(0xc);  esc("E");
  129. }
  130. static void putint(i)  short i;  {
  131.   if (i >= 10)  putint(i / 10);
  132.   put(i % 10 + '0');
  133. }
  134. static void putbits(c, pbuf)  char c;  uchar pbuf[linl+1]; {
  135.   uchar qbuf[linl+1];  short i, j, k, l, m, n;  uchar b, ba;
  136.   n = xmb;  while (pbuf[n] == 0 && n >= 0) n--;
  137.   if (n < 0)  m = 0;  else {
  138.     b = pbuf[0];  j = 1;  k = 2;  l = 2;  qbuf[k] = b;
  139.     for (i = 1; i <= n; i++) {  ba = b;  b = pbuf[i];
  140.       if (ba == b) {
  141.     if (l == k) {
  142.       if (k == j + 1)  k--;  else {
  143.         l++;  qbuf[l] = b;
  144.         if (l - j >= 128) {  qbuf[j] = k - j - 2;  j = k;  }
  145.     } } else {  l++;
  146.       if (j < k) {  qbuf[j] = k - j - 2;  j = k;  }
  147.       if (l - j >= 128) {
  148.         qbuf[j] = 129;  j = k + 2;  k = j + 1;  l = k;  qbuf[k] = b;
  149.       }    } } else {
  150.     if (l == k) {  k++;
  151.       if (k - j > 128) {  qbuf[j] = k - j - 2;  j = k;  k++;  }
  152.       qbuf[k] = b;  l = k;
  153.     } else if (j == k) {  qbuf[j] = k - l + 256;
  154.       j += 2;  k = j + 1;  l = k;  qbuf[k] = b;
  155.     } else {  l++;  k = l;  qbuf[k] = b;
  156.     } } }
  157.     if (l == k)        { qbuf[j] = l - j - 1;   m = l;
  158.     } else if (j == k) { qbuf[j] = k - l + 256; m = j + 1;
  159.     } else             { qbuf[j] = l - j - 1;   m = l;
  160.   } }
  161.   esc("*b");  putint(m);  put(c);
  162.   for (i = 1; i <= m; i++)  put(qbuf[i]);
  163. }
  164. static short skipper;
  165. static void hardcopy()  {  uchar pbuf[linl+1];
  166.   short x, y;  uchar b,nothing;  colpix *WITH;
  167.   propen();
  168.   if (zilli == 0) {
  169.     esc("E");
  170. #ifdef DINA4
  171.     esc("&l26A");
  172. #endif
  173.     esc("&a1N");  esc("*r2360S");  esc("*t300R");
  174. #ifdef DJ550C
  175.     esc("*r-4U");
  176. #endif
  177. #ifdef DJ500C
  178.     esc("*r-3U");
  179. #endif
  180.     esc("*p0x0Y");  esc("*r0A");  esc("*b2M"); skipper=0;
  181.   }
  182.   for (y = 0; y <= ymax; y++) { nothing=1;
  183.     for (x = 0; x <= xmb; x++) {  WITH = &pxlmem[y][x];
  184. #ifdef DJCOLOUR
  185.       b = WITH->kpix | (WITH->cpix & WITH->mpix & WITH->ypix);
  186. #else
  187.       b = WITH->kpix | (WITH->cpix | WITH->mpix | WITH->ypix);
  188. #endif
  189.       WITH->kpix = b;
  190. #ifdef DJ550C
  191.       b = ~b; WITH->cpix &= b;  WITH->mpix &= b;  WITH->ypix &= b;
  192. #endif
  193. #ifdef DJ500C
  194.       WITH->kpix = WITH->cpix | b;  WITH->mpix |= b;  WITH->ypix |= b;
  195. #endif
  196.       if(WITH->kpix|WITH->cpix|WITH->mpix|WITH->ypix) nothing=0;
  197.     }
  198.     if(nothing) skipper++; else {
  199.       if(skipper>0) { esc("*b"); putint(skipper); put('Y'); skipper=0; }
  200.       for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].kpix;
  201. #ifdef DJ550C
  202.       putbits('V', pbuf);
  203.       for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].cpix;
  204. #endif
  205. #ifdef DJCOLOUR
  206.       putbits('V', pbuf);
  207.       for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].mpix;
  208.       putbits('V', pbuf);
  209.       for (x = 0; x <= xmb; x++) pbuf[x] = pxlmem[y][x].ypix;
  210. #endif
  211.       putbits('W', pbuf);
  212. } } prflush(); }
  213. static void pixet(y, x, b)  ushort y, x;  uchar b;  {
  214.   colpix *WITH;  greydesc *WITH1;
  215.   WITH = &pxlmem[y][x];  WITH1 = &greymask[y & 7];
  216.   if (clearing) {  WITH->cpix &= ~b;  WITH->mpix &= ~b;
  217.     WITH->ypix &= ~b;  WITH->kpix &= ~b;  return;
  218.   }
  219.   WITH->cpix |= b & WITH1->maskc;  WITH->mpix |= b & WITH1->maskm;
  220.   WITH->ypix |= b & WITH1->masky;  WITH->kpix |= b & WITH1->maskk;
  221. }
  222. static void setrect(xl, yl, xh, yh)  ushort xl, yl, xh, yh;  {
  223.   ushort x, y, xll, xrr;  uchar a, b, c;
  224.   xll = xl >> 3;  xrr = xh >> 3;
  225.   a = (0xff >> (xl & 7)) & 255;  c = 0xff << (7 - (xh & 7));
  226.   for (y = yl; y <= yh; y++) {  b = a;
  227.     for (x = xll; x <= xrr; x++) {
  228.       if (x == xrr)  b &= c;
  229.       pixet(y, x, b);  b = 0xff;
  230. } } }
  231. /*static long prodovz(a, b)  ushort a, b;  {  return ((long)a * (long)b);  }
  232. static long scaled(w, z)  long w, z;  {  long s;
  233.   union {  long l;  struct {  ushort n, h;  } U1;  } a, b;
  234.   a.l = w;  b.l = z;
  235.   s = (((((ulong)prodovz(a.U1.n, b.U1.n)) >> 16) + prodovz(a.U1.n,
  236.       b.U1.h) + prodovz(a.U1.h, b.U1.n)) >> 4) +
  237.       (prodovz(a.U1.h, b.U1.h) << 12);
  238.   if (w < 0)  s -= z << 12;  return s;
  239. } */
  240. static long scaled(w, z)  long w, z;  {  long s; ulong t=w, u=z;
  241.   /* should return  w * z / 2**20  */
  242.   s = ( ( (((t & 65535L) * (u & 65535L)) >> 16)
  243.     +   (t & 65535L) * (u >>    16)
  244.     +   (t >>    16) * (u & 65535L)         ) >> 4)
  245.     + ( (   (t >>    16) * (u >>    16)         ) << 12);
  246.   if (w < 0)  s -= z << 12;  return s;
  247. }
  248. static char dviname[73];
  249. static FILE *dvifile;
  250. static long dvimag;
  251. static uchar dvibuf[2048];
  252. static ushort dvibufp, dvibufe;
  253.  
  254. static void baddvi(s)  char *s;  {
  255.   fprintf(prot, "bad dvi: %s\n", s);  exit(1);
  256. }
  257. static void dvibytes(s, l)   char *s;  uchar l;  {  ushort ll;
  258.   s[l] = '\0';  ll = dvibufe - dvibufp;
  259.   if (ll >= l) {
  260.     memmove((ptr)s, (ptr)(&dvibuf[dvibufp]), (long)l);
  261.     dvibufp += l;  return;
  262.   }
  263.   if (ll > 0)  memmove((ptr)s, (ptr)(&dvibuf[dvibufp]), (long)ll);
  264.   dvibufe = fread(dvibuf, 1, 2048, dvifile);
  265.   if (dvibufe + ll < l)  baddvi("ends prematurely !");
  266.   memmove((ptr)(&s[ll]), (ptr)dvibuf, (long)(l - ll));
  267.   dvibufp = l - ll;
  268. }
  269. static uchar dvibyte() { uchar b;
  270.   if (dvibufp >= dvibufe) {  dvibufp = 0;
  271.     dvibufe = fread(dvibuf, 1, 2048, dvifile);
  272.   }
  273.   if (dvibufp >= dvibufe)  baddvi("ends prematurely !");
  274.   b = dvibuf[dvibufp];  dvibufp++;  return b;
  275. }
  276. static void dviskip(l)  long l;  {  uchar b;
  277.   while (l > 0) {
  278.     l += (long)dvibufp - (long)dvibufe;
  279.     if (l <= 0)  dvibufp = dvibufe + l;
  280.     else {  dvibufp = dvibufe;  l--;  dvibyte();  }
  281. } }
  282. static long dvinum(b)  uchar b;  {  uchar i;  long n;
  283.   n = 0;
  284.   if (dvibufp + b > dvibufe) {
  285.     for (i = 1; i <= b; i++)  n = (n << 8) | dvibyte();  return n;
  286.   }
  287.   for (i = 0; i < b; i++)  n = (n << 8) | dvibuf[dvibufp + i];
  288.   dvibufp += b;  return n;
  289. }
  290. static long dviint(b)  uchar b;  {  uchar i;  long n;
  291.   if (dvibufp + b <= dvibufe) {
  292.     n = dvibuf[dvibufp];
  293.     if (n > 127)  n -= 256;
  294.     for (i = 1; i < b; i++)  n = (n << 8) | dvibuf[dvibufp + i];
  295.     dvibufp += b;  return n;
  296.   }
  297.   n = dvibyte();
  298.   if (n > 127)  n -= 256;
  299.   for (i = 2; i <= b; i++)  n = (n << 8) | dvibyte();  return n;
  300. }
  301. static void dviposit(l)  long l;  {  fseek(dvifile, l, 0);
  302.   dvibufe = fread(dvibuf, 1, 2048, dvifile);  dvibufp = 0;
  303. }
  304. static void dviopen() {  long l;  uchar j, em;  ushort k;
  305.   sprintf(STR, "%s.dvi", dviname);
  306.   if ((dvifile = fopen(STR, "rb"))==0) {  strcpy(STR, dviname);
  307.     if ((dvifile = fopen(STR, "rb"))==0)  baddvi("not existing !");
  308.   }
  309.   dvibufe = fread(dvibuf, 1, 2, dvifile);
  310.   if (dvibufe < 2) baddvi("empty !");
  311.   em = dvibuf[1];
  312.   if (dvibuf[0] != 247) baddvi("no valid preamble");
  313.   /* now position to postamble */
  314.   fseek(dvifile, 0L, 2);  l=ftell(dvifile);  if(l>2048) l=2048;
  315.   fseek(dvifile, -l, 2);  k = fread(dvibuf, 1, 2048, dvifile);
  316.   do {  k--;  } while (k >= 4 && dvibuf[k] != em);
  317.   if (k < 4)  baddvi("no postamble in last 2048 bytes !");
  318.   dvibufe = k + 1;  dvibufp = k - 4;  l = dvinum(4);
  319.   fseek(dvifile, l, 0);  dvibufe = fread(dvibuf, 1, 2048, dvifile);
  320.   dvibufp = 0;  dvibyte();
  321. }
  322.  
  323. typedef union chdesc { uchar b8[16];
  324.   struct { short wid, hei, hof, vof; long bmp, tfw; } U1;
  325.   struct { long tfh, tfd, dum1, dum2; } U2;
  326. } chdesc;
  327. typedef struct fontdesc {
  328.   long dfn;  char *fonam;  chdesc *chv;
  329.   long danf;  uchar *chm;  short mch, fty;
  330. } fontdesc;
  331. static fontdesc **fontvect;
  332. static uchar fontint;
  333. static FILE *fofil;
  334. static uchar *achm;
  335. static uchar fofbyte() {  uchar b;
  336.   if (fread(&b, 1, 1, fofil) <= 0) b = 0;  return b;
  337. }
  338. static long fofint(b)  uchar b;  {  uchar i;  long n;
  339.   n = fofbyte();  if (n > 127)  n -= 256;
  340.   for (i = 2; i <= b; i++)  n = (n << 8) | fofbyte();
  341.   return n;
  342. }
  343.  
  344. static long hs[smax], vs[smax], ws[smax], xs[smax], ys[smax], zs[smax];
  345. static long cnt[10];
  346. static uchar bitrev[256];
  347. static char comment[256];
  348. static double conv, vconv;
  349. static long l, landx, landy, newmag;
  350. static long a, b, c, f, q, h, v, hoff, voff, w, x, y, z;
  351. static long chk, scf, dsz, fofchk, num, den, mag, spl, lpp, mxh, mxv;
  352. static int pagnum, pag1, paganz, i, k;
  353. static ushort s, mst, mpn;
  354. static char dviori;
  355. static uchar o, j, post, fini, started, below;
  356.  
  357. static void initbitrev() {  uchar b, i, j, k, m, n;
  358.   for (m = 0; m <= 3; m++) { n=m;
  359. #ifdef DJCOLOUR
  360.     n=3;
  361. #endif
  362.     for (i = 0; i <= maxink; i++) {
  363.       for (j = 0; j <= 3; j++) {  b = 0;
  364.         for (k = 0; k <= 3; k++) {
  365.         if (maskmat[n][j][k] <= i)  b |= maskmat[4][0][k];
  366.   }  maskb[i][m][j] = b;  } } }
  367.   bitrev[0] = 0;  m = 0x80;  n = 1;
  368.   while (m) {  /* put bits into reverse order within a byte */
  369.     for (j = 0; j < n; j++)  bitrev[j + n] = bitrev[j] | m;
  370.     n += n;  m >>= 1;
  371. } }
  372.  
  373. static void tfmdef() {  short ll, lh, bc, ec, nw, nh, nd, i;
  374.   uchar b1, b2, b3;  short FORLIM;
  375.   fontdesc *WITH = fontvect[fontint];
  376.   sprintf(STR, "%s%s.tfm", tfmprefix, FONAM);
  377.   fprintf(prot, "trying  %s  instead", STR);
  378.   fofil = fopen(STR, "rb");
  379.   if (fofil==0) {  fprintf(prot, " - absent as well :-(\n");  return;  }
  380.   ll = fofint(2);  lh = fofint(2);  bc = fofint(2);  ec = fofint(2);
  381.   nw = fofint(2);  nh = fofint(2);  nd = fofint(2);  fseek(fofil, 0L, 2);
  382.   if (ll * 4 > ftell(fofil) || ll < lh + ec - bc + nw + nh + nd + 7) {
  383.     fprintf(prot, " - not a TFMfile !\n");  fclose(fofil);  return;
  384.   }
  385.   WITH->mch = ec;
  386.   Tptr( WITH->chv = (chdesc *)calloc(WITH->mch + 1, sizeof(chdesc)) );
  387.   fseek(fofil, 24L, 0);  fofchk = fofint(4);
  388.   if (chk != 0) if (fofchk != 0) if (chk != fofchk)
  389.     fprintf(prot, " *+* wrong checksum *+* ");
  390.   fseek(fofil, (lh + ec - bc + 7L) * 4, 0);
  391.   FORLIM = nw + nh + nd;
  392.   for (i = 0; i < FORLIM; i++)
  393.     WITH->chv[i].U2.dum1 = scaled(fofint(4), scf);
  394.   fseek(fofil, lh * 4L + 24, 0);
  395.   for (i = bc; i <= ec; i++) {
  396.     b1 = fofbyte();  b2 = fofbyte();  fofbyte();  fofbyte();
  397.     WITH->chv[i].U1.tfw = WITH->chv[b1].U2.dum1;
  398.     WITH->chv[i].U2.tfh = WITH->chv[nw + (b2 >> 4)].U2.dum1;
  399.     WITH->chv[i].U2.tfd = WITH->chv[nw + nh + (b2 & 15)].U2.dum1;
  400.   }
  401.   fclose(fofil);  WITH->fty = 1;  fprintf(prot, " - TFMfile OK\n");
  402. }
  403. static void tfmchar() {  short hr, vr, br, ar;  uchar li, re, ob, un;
  404.   chdesc *WITH = &fontvect[fontint]->chv[c];
  405.   switch (dviori) {
  406.   case 0:
  407.     hr = (long)(conv * h + 0.5);
  408.     vr = (long)(vconv * (v - WITH->U2.tfh) + 0.5);
  409.     br = (long)(conv * (h + WITH->U1.tfw) + 0.5);
  410.     ar = (long)(vconv * (v + WITH->U2.tfd) + 0.5);
  411.     break;
  412.   case 1:
  413.     hr = (long)(conv * (landx + v - WITH->U2.tfh) + 0.5);
  414.     vr = (long)(vconv * (landy - h - WITH->U1.tfw) + 0.5);
  415.     br = (long)(conv * (landx + v + WITH->U2.tfd) + 0.5);
  416.     ar = (long)(vconv * (landy - h) + 0.5);
  417.     break;
  418.   case 3:
  419.     hr = (long)(conv * (landx - v - WITH->U2.tfd) + 0.5);
  420.     vr = (long)(vconv * (landy + h) + 0.5);
  421.     br = (long)(conv * (landx - v + WITH->U2.tfh) + 0.5);
  422.     ar = (long)(vconv * (landy + h + WITH->U1.tfw) + 0.5);
  423.     break;
  424.   case 2:
  425.     hr = (long)(conv * (landx - h - WITH->U1.tfw) + 0.5);
  426.     vr = (long)(vconv * (landy - v - WITH->U2.tfd) + 0.5);
  427.     br = (long)(conv * (landx - h) + 0.5);
  428.     ar = (long)(vconv * (landy - v + WITH->U2.tfh) + 0.5);
  429.     break;
  430.   }
  431.   li = 1;  re = 1;  ob = 1;  un = 1;
  432.   if (hr < 0) {  hr = 0;  li = 0;  }
  433.   if (br > xmax) {  br = xmax;  re = 0;  }
  434.   vr -= zilli;  ar -= zilli;
  435.   if (vr < 0) {  vr = 0;  ob = 0;  }
  436.   if (ar > ymax) {  ar = ymax;  un = 0;  below = 1;  }
  437.   if (hr > br)  return;
  438.   if (vr > ar)  return;
  439.   if (ob)  setrect(hr, vr, br, vr);
  440.   if (li)  setrect(hr, vr, hr, ar);
  441.   if (un)  setrect(hr, ar, br, ar);
  442.   if (re)  setrect(br, vr, br, ar);
  443. }
  444.  
  445. static ushort pkpos;
  446. static uchar pkn1()  {  uchar Result;
  447.   Result = achm[pkpos];  pkpos++;  return Result;
  448. }
  449. static short pki1()  {  short b;
  450.   b = pkn1();  if (b > 127)  b -= 256;  return b;
  451. }
  452. static short pkn2()  {  short b;
  453.   b = pkn1();  return (b * 256 + pkn1());
  454. }
  455. static short pki2()  {  short b;
  456.   b = pkn1();  if (b > 127)  b -= 256;
  457.   return (b * 256 + pkn1());
  458. }
  459. static long pkn3()  {  long b;  short c;
  460.   b = pkn1();  c = pkn1();
  461.   return ((b * 256 + c) * 256 + pkn1());
  462. }
  463. static long pki3()  {  long b;
  464.   b = pki1();  return (b * 65536L + pkn2());
  465. }
  466. static long pki4()  {  long b;
  467.   b = pki2();  return (b * 65536L + pkn2());
  468. }
  469. static void pkdef()  {  long a, l;  ushort d;  uchar b, bb;
  470.   uchar terminate;  short i, j, c;  fontdesc *WITH;  chdesc *WITH1;
  471.   WITH = fontvect[fontint];  sprintf(STR, "%spk", FOFUL);
  472.   fprintf(prot,"preparing font %ld: %s", f, STR);
  473.   if( (fofil = fopen(STR, "rb"))==0) {
  474.     fprintf(prot," not found :-(\n");
  475.     sprintf(STR, "%spk", FOLOC);
  476.     fprintf(prot,"preparing font %ld: %s", f, STR);
  477.     fofil = fopen(STR, "rb");
  478.   }
  479.   if (fofil==0) {  WITH->mch = -1;
  480.     fprintf(prot, " - file not found !\n");  return;
  481.   }
  482.   if ((fgetc(fofil)!=0xf7)||(fgetc(fofil)!=0x59)){  WITH->mch = -1;
  483.     fprintf(prot, " - not a PKfile !\n");  fclose(fofil);  return;
  484.   } else {
  485.     fseek(fofil, 0L, 2);  WITH->danf = ftell(fofil);
  486.     if (WITH->danf > 65520L) {  WITH->mch = -1;  fclose(fofil);
  487.       fprintf(prot, " - too big for this driver\n");  return;
  488.     } else {
  489.       Tptr( WITH->chv = (chdesc *)calloc(256, sizeof(chdesc)) );
  490.       Tptr( achm = (uchar *)malloc(WITH->danf) );
  491.       fseek(fofil, 0L, 0);  fread(achm, WITH->danf, 1, fofil);
  492.       fclose(fofil);  WITH->mch = -1;  pkpos = 0;  terminate = 0;
  493.       do {  b = pkn1();
  494.     if (b >= 240) {
  495.       switch (b) {
  496.       case 240:  case 241:  case 242:  case 243: l = 0;
  497.         for (i = 240; i <= b; i++)  l = (l << 8) + pkn1();
  498.         pkpos += l;  break;
  499.       case 244:  pkpos += 4;  break;
  500.       case 245:  terminate = 1;  break;
  501.       case 246:  break;
  502.       case 247:  b = pkn1();  i = pkn1();
  503.         pkpos += i + 4;  fofchk = pki4();
  504.         if (chk != 0) if (fofchk != 0) if (chk != fofchk)
  505.              fprintf(prot, " *+* wrong checksum *+* ");
  506.             pkpos += 8;  break;
  507.       case 248:  case 249:  case 250:  case 251:
  508.       case 252:  case 253:  case 254:  case 255:  break;
  509.       }
  510.     } else {  d = pkpos - 1;  bb = b & 7;
  511.       switch (bb) {
  512.       case 0:  case 1:  case 2:  case 3:
  513.         l = bb * 256 + pkn1() - 8;  c = pkn1();  break;
  514.       case 4:  case 5:  case 6:  l = bb - 4;
  515.         l = (l << 16) + pkn2() - 13;  c = pkn1();  break;
  516.       case 7:  l = pki4() - 28;  c = pki4();  break;
  517.       }
  518.       WITH1 = &WITH->chv[c];
  519.       switch (bb) {
  520.       case 0:  case 1:  case 2:  case 3:
  521.         WITH1->U1.tfw = scaled(pkn3(), scf);  pkn1();
  522.         WITH1->U1.wid = pkn1();  WITH1->U1.hei = pkn1();
  523.             WITH1->U1.hof = pki1();  WITH1->U1.vof = pki1();  break;
  524.       case 4:  case 5:  case 6:
  525.         WITH1->U1.tfw = scaled(pkn3(), scf);  pkn2();
  526.         WITH1->U1.wid = pkn2();  WITH1->U1.hei = pkn2();
  527.             WITH1->U1.hof = pki2();  WITH1->U1.vof = pki2();  break;
  528.       case 7:
  529.         WITH1->U1.tfw = scaled(pki4(), scf);  pki4();  pki4();
  530.         WITH1->U1.wid = pki4();   WITH1->U1.hei = pki4();
  531.             WITH1->U1.hof = pki4();   WITH1->U1.vof = pki4();  break;
  532.       }
  533.       pkpos += l;
  534.       if ((unsigned)c <= 255) {
  535.         if (WITH->mch < c)  WITH->mch = c;
  536.         WITH->chv[c].U1.bmp = d;
  537.       }    } } while (!terminate); free(achm);
  538.       if (WITH->mch < 0)  fprintf(prot, " - PKfile in error !\n");
  539.        else  fprintf(prot, " - available\n");
  540.       WITH->chv = (chdesc *) realloc(WITH->chv, 16*(WITH->mch + 1));
  541.       Tptr( WITH->fonam = (char *) malloc(strlen(STR)+1) );
  542.       strcpy(WITH->fonam, STR);
  543. } } }
  544. static struct  {  short xs, x, wid1;  short ii, j;
  545.   uchar dd, db;  ushort d;  uchar white;  uchar buf[xmb + 1];
  546.   uchar bmerk;  long repc, count;  short dynf, dyng, dynh;
  547. }  Lpkc;
  548. static uchar pknib()  {  uchar Result;
  549.   if (Lpkc.bmerk != 0) {
  550.     Result = Lpkc.bmerk & 0xf;  Lpkc.bmerk = 0;  return Result;
  551.   }
  552.   Lpkc.bmerk = pkn1();  Result = Lpkc.bmerk >> 4;
  553.   Lpkc.bmerk |= 0xf0;  return Result;
  554. }
  555. static long pknum()  {  uchar i, j, k;  long n;
  556.   k = 1;
  557.   do {  i = pknib();  k++;
  558.     if (i == 0) {
  559.       do {  j = pknib();  i++;  } while (j == 0);
  560.       n = j;
  561.       while (i > 0) {  i--;  n = (n << 4) + pknib();  }
  562.       n += Lpkc.dyng;
  563.     } else if (i <= Lpkc.dynf)  n = i;
  564.     else if (i < 14)  n = (i << 4) + pknib() + Lpkc.dynh;
  565.     else if (i == 14)  k = 0;
  566.     else {  k = 1;  n = 1;  }
  567.     if (k == 1)  Lpkc.repc = n;
  568.   } while (k != 2);  return n;
  569. }
  570. static void pkline()  {
  571.   if (Lpkc.dynf == 14) {
  572.     Lpkc.j = Lpkc.wid1 + Lpkc.xs;
  573.     Lpkc.db += Lpkc.xs;
  574.     do {
  575.       if (Lpkc.db < 8)    Lpkc.d = (Lpkc.d << 8) | pkn1();
  576.       else  Lpkc.db -= 8;
  577.       Lpkc.dd = (Lpkc.d >> Lpkc.db) & 255;
  578.       if (Lpkc.j >= 8) {  Lpkc.j -= 8;    Lpkc.buf[Lpkc.x] = Lpkc.dd;
  579.       } else {    Lpkc.db += 8 - Lpkc.j;
  580.     Lpkc.buf[Lpkc.x] = Lpkc.dd & (0xff00L >> Lpkc.j) & 255;
  581.     Lpkc.j = 0;
  582.       }  Lpkc.x++;
  583.     } while (Lpkc.j != 0);
  584.     Lpkc.d &= 0xffffL >> (16 - Lpkc.db);  return;
  585.   }
  586.   Lpkc.ii = 0;  Lpkc.j = Lpkc.wid1;  Lpkc.db = 8 - Lpkc.xs;  Lpkc.d = 0;
  587.   if (Lpkc.repc > 0) {  Lpkc.repc--;  return;  }
  588.   while (Lpkc.j > 0) {
  589.     if (Lpkc.count == 0) { Lpkc.count = pknum();  Lpkc.white = !Lpkc.white; }
  590.     Lpkc.dd = Lpkc.db;
  591.     if (Lpkc.dd > Lpkc.j)  Lpkc.dd = Lpkc.j;
  592.     if (Lpkc.dd > Lpkc.count)  Lpkc.dd = Lpkc.count;
  593.     if (Lpkc.white)  Lpkc.db -= Lpkc.dd;
  594.     else {  Lpkc.d += 1 << Lpkc.db;
  595.       Lpkc.db -= Lpkc.dd;  Lpkc.d -= 1 << Lpkc.db;
  596.     }
  597.     Lpkc.count -= Lpkc.dd;  Lpkc.j -= Lpkc.dd;
  598.     if (Lpkc.db == 0 || Lpkc.j == 0) {
  599.       Lpkc.buf[Lpkc.x] = Lpkc.d & 255;
  600.       Lpkc.x++;  Lpkc.d = 0;  Lpkc.db = 8;
  601. } } }
  602. static void pkchar()  {  short hr, vr;  long bma, bmx;
  603.   short x1, x2, x3, y1, y2, y;  uchar b, bb, mach, mac, mpm, bach;
  604.   fontdesc *WITH;  chdesc *WITH1;
  605.   WITH = fontvect[fontint];  WITH1 = &WITH->chv[c];
  606.   pkpos = WITH1->U1.bmp;  b = pkn1();
  607.   Lpkc.white = ((b & 8) == 0);  Lpkc.wid1 = WITH1->U1.wid;
  608.   Lpkc.dynf = b >> 4;
  609.   Lpkc.dyng = (13 - Lpkc.dynf) * 16 + Lpkc.dynf - 15;
  610.   Lpkc.dynh = -(Lpkc.dynf + 1) * 15;  bb = b & 7;
  611.   switch (bb) {
  612.   case 0:  case 1:  case 2:  case 3:  pkpos += 10;  break;
  613.   case 4:  case 5:  case 6:  pkpos += 16;  break;
  614.   case 7:  pkpos += 36;  break;
  615.   }
  616.   Lpkc.bmerk = 0;  Lpkc.d = 0;  Lpkc.db = 0;  Lpkc.repc = 0;
  617.   Lpkc.count = 0;  Lpkc.white = !Lpkc.white;
  618.   switch (dviori) {
  619.   case 0:
  620.     hr = (long)(conv * h + 0.5) - WITH1->U1.hof;
  621.     vr = (long)(vconv * v + 0.5) - WITH1->U1.vof - zilli;
  622.     if (vr > ymax)  below = 1;  else {
  623.       if (vr + WITH1->U1.hei >= 1) {
  624.     x1 = hr / 8;  x2 = (hr + WITH1->U1.wid - 1) / 8;
  625.     Lpkc.xs = hr & 7;    y2 = vr + WITH1->U1.hei - 1;
  626.     if (y2 > ymax) {  y2 = ymax;  below = 1;  }
  627.     if (0 <= x1) {
  628.       if (x2 <= xmb) {
  629.         for (y = vr; y <= y2; y++) {
  630.           Lpkc.x = x1;  pkline();
  631.           if (y >= 0) {
  632.         for (Lpkc.x = x1; Lpkc.x <= x2; Lpkc.x++)
  633.           pixet(y, Lpkc.x, Lpkc.buf[Lpkc.x]);
  634.     } } } } } }  break;
  635.   case 1:
  636.     hr = (long)(conv * (landx + v) + 0.5) - WITH1->U1.vof;
  637.     vr = (long)(vconv * (landy - h) + 0.5) + WITH1->U1.hof - zilli;
  638.     if (vr - WITH1->U1.wid + 1 > ymax)  below = 1;  else {
  639.       if (vr >= 0) {  Lpkc.xs = 0;  mac = 0x80;  bma = 0;    y1 = vr;
  640.     if (y1 > ymax) {  below = 1;  bma += ((ulong)(y1 - ymax)) >> 3;
  641.       mac = 0x80 >> ((y1 - ymax) & 7);  y1 = ymax;
  642.     }
  643.     y2 = vr - WITH1->U1.wid + 1;  if (y2 < 0)  y2 = 0;
  644.     x2 = hr + WITH1->U1.hei - 1;  if (x2 > xmax)  x2 = xmax;
  645.     for (x3 = hr; x3 <= x2; x3++) {
  646.       Lpkc.x = 0;  pkline();
  647.       if (x3 >= 0) {
  648.         mach = mac;  Lpkc.x = ((unsigned)x3) >> 3;
  649.         mpm = 0x80 >> (x3 & 7);  bmx = bma;  bach = Lpkc.buf[bmx];
  650.         for (y = y1; y >= y2; y--) {
  651.           if ((bach & mach) != 0)  pixet(y, Lpkc.x, mpm);
  652.           mach >>= 1;
  653.           if (mach == 0) {
  654.         mach = 0x80;  bmx++;  bach = Lpkc.buf[bmx];
  655.     } } } } } }  break;
  656.   case 3:
  657.     hr = (long)(conv * (landx - v) + 0.5) + WITH1->U1.vof;
  658.     vr = (long)(vconv * (landy + h) + 0.5) - WITH1->U1.hof - zilli;
  659.     if (vr > ymax)  below = 1;  else {
  660.       if (vr + WITH1->U1.wid >= 1) {
  661.     Lpkc.xs = 0;  mac = 0x80;  bma = 0;  y1 = vr;
  662.     if (y1 < 0) {  bma += ((unsigned)(-y1)) >> 3;
  663.       mac = 0x80 >> ((-y1) & 7);  y1 = 0;
  664.     }
  665.     y2 = vr + WITH1->U1.wid - 1;
  666.     if (y2 > ymax) {  y2 = ymax;  below = 1;  }
  667.     x2 = hr - WITH1->U1.hei + 1;  if (x2 < 0)  x2 = 0;
  668.     for (x3 = hr; x3 >= x2; x3--) {
  669.       Lpkc.x = 0;  pkline();
  670.       if (x3 <= xmax) {
  671.         mach = mac;  Lpkc.x = ((unsigned)x3) >> 3;
  672.         mpm = 0x80 >> (x3 & 7);  bmx = bma;  bach = Lpkc.buf[bmx];
  673.         for (y = y1; y <= y2; y++) {
  674.           if ((bach & mach) != 0)  pixet(y, Lpkc.x, mpm);
  675.           mach >>= 1;
  676.           if (mach == 0) {
  677.         mach = 0x80;  bmx++;  bach = Lpkc.buf[bmx];
  678.     } } } } } }  break;
  679.   case 2:
  680.     hr = (long)(conv * (landx - h) + 0.5) + WITH1->U1.hof;
  681.     vr = (long)(vconv * (landy - v) + 0.5) + WITH1->U1.vof - zilli;
  682.     if (vr - WITH1->U1.hei + 1 > ymax)  below = 1;  else {
  683.       if (vr >= 0) {
  684.     x1 = hr / 8;  x2 = (hr - WITH1->U1.wid + 1) / 8;
  685.     Lpkc.xs = (7 - hr) & 7;  y2 = vr - WITH1->U1.hei + 1;
  686.     if (y2 < 0)  y2 = 0;
  687.     if (vr > ymax)  below = 1;
  688.     if (0 <= x2) {
  689.       if (x1 <= xmb) {
  690.         for (y = vr; y >= y2; y--) {
  691.           Lpkc.x = xmb - x1;  pkline();
  692.           if (y <= ymax) {
  693.         for (Lpkc.x = x1; Lpkc.x >= x2; Lpkc.x--)
  694.           pixet(y, Lpkc.x, bitrev[Lpkc.buf[xmb - Lpkc.x]]);
  695.     } } } } } }  break;
  696. } }
  697.  
  698. static void fontdef() {  uchar a, b, p, q;  fontdesc *WITH;
  699.   if (f < 0)  baddvi("negative fontnumber");
  700.   b = f & 0xff;  a = 0;
  701.   if ((f > 255) || (fontvect[b] != NULL)) do {
  702.     if (fontvect[a] == NULL)  b = a;
  703.     else if (fontvect[a]->dfn == f)  baddvi("double fontnumber");
  704.     a++;
  705.   } while (a);
  706.   if (fontvect[b] != NULL)  baddvi("too many fonts");
  707.   fontint = b;
  708.   Tptr( fontvect[b] = (fontdesc *)malloc(sizeof(fontdesc)) );
  709.   WITH = fontvect[fontint];  WITH->dfn = f;
  710.   chk = dvinum(4);  scf = dvinum(4);  dsz = dvinum(4);
  711.   WITH->chm = NULL;  WITH->fty = -1;
  712.   p = dvibyte();  q = dvibyte();  dvibytes(FONAM, q);
  713.   if (p == 0)  strcpy(FOPRE, fontprefix);  else dvibytes(FOPRE, p);
  714.   sprintf(FOMAG, "%ld",
  715.       (long)(xres * dvimag / 1000.0 * ((double)scf / dsz) + 0.5));
  716. #ifdef __MSDOS__
  717.   sprintf(FOFUL, "%s%s\\%s.", FOPRE, FOMAG, FONAM);
  718.   sprintf(FOLOC, "%s.", FONAM);
  719. #else
  720.   sprintf(FOFUL, "%s%s.%s", FOPRE, FONAM, FOMAG);
  721.   sprintf(FOLOC, "%s.%s", FONAM, FOMAG);
  722. #endif
  723.   pkdef();  if (WITH->mch < 0)  tfmdef();
  724. }
  725.  
  726. static void fontlod() { uchar b = 0;
  727.   fontdesc *WITH = fontvect[fontint];
  728.   WITH->chm = (uchar *)malloc(WITH->danf);
  729.   if (WITH->chm == NULL) { do {
  730.       if (fontvect[b] != NULL) {
  731.     if (fontvect[b]->chm) free(fontvect[b]->chm);
  732.     fontvect[b]->chm = NULL;
  733.       }  b++;
  734.     } while (b);
  735.     Tptr( WITH->chm = (uchar *)malloc(WITH->danf) );
  736.   }
  737.   fofil = fopen(WITH->fonam, "rb");
  738.   fread(WITH->chm, WITH->danf, 1, fofil);  fclose(fofil);
  739. }
  740.  
  741. static void fontset() {  uchar a, b, x;
  742.   b = f & 0xff;  x = 0;
  743.   if (fontvect[b] != NULL)  if (fontvect[b]->dfn == f)  x = 1;
  744.   if (x == 0) {  a = 0;
  745.     do {
  746.       if (fontvect[a] == NULL)    a++;
  747.       else if (fontvect[a]->dfn != f)  a++;
  748.       else {  x = 1;  b = a;  a = 0;  }
  749.     } while (a != 0);
  750.   }
  751.   if (x == 0)  baddvi("undefined fontnumber");
  752.   fontint = b;
  753. }
  754. static void putrule() {  short hr, vr, br, ar;
  755.   if (b <= 0)  return;
  756.   switch (dviori) {
  757.   case 0:
  758.     hr = (long)(conv * h + 0.5);
  759.     vr = (long)(vconv * (v - a) + 0.5);
  760.     br = (long)(conv * b + 0.5);  if (br > 0)  br--;
  761.     ar = (long)(vconv * a + 0.5);
  762.     break;
  763.   case 1:
  764.     hr = (long)(conv * (landx + v - a) + 0.5);
  765.     vr = (long)(vconv * (landy - h - b) + 0.5);
  766.     br = (long)(conv * a + 0.5);
  767.     ar = (long)(vconv * b + 0.5);  if (ar > 0)  ar--;
  768.     break;
  769.   case 3:
  770.     hr = (long)(conv * (landx - v) + 0.5);
  771.     vr = (long)(vconv * (landy + h) + 0.5);
  772.     br = (long)(conv * a + 0.5);
  773.     ar = (long)(vconv * b + 0.5);  if (ar > 0)  ar--;
  774.     break;
  775.   case 2:
  776.     hr = (long)(conv * (landx - h - b) + 0.5);
  777.     vr = (long)(vconv * (landy - v) + 0.5);
  778.     br = (long)(conv * b + 0.5);  if (br > 0)  br--;
  779.     ar = (long)(vconv * a + 0.5);
  780.     break;
  781.   }
  782.   vr -= zilli;  ar += vr;  br += hr;
  783.   if (hr < 0)  hr = 0;
  784.   if (br > xmax)  br = xmax;
  785.   if (vr < 0)  vr = 0;
  786.   if (ar > ymax) {  ar = ymax;  below = 1;  }
  787.   if (hr <= br)  if (vr <= ar)  setrect(hr, vr, br, ar);
  788. }
  789. static void putchar_() {  fontdesc *WITH;  chdesc *WITH1;
  790.   WITH = fontvect[fontint];
  791.   if (c > WITH->mch) {  q = 0;  return;  }
  792.   WITH1 = &WITH->chv[c];  q = WITH1->U1.tfw;
  793.   if (WITH->fty == 1) {  tfmchar();  return;  }
  794.   if (WITH1->U1.bmp == 0)  return;
  795.   if (WITH->chm == NULL)  fontlod();
  796.   achm = WITH->chm;  pkchar();
  797. }
  798. static void clrpxlmem() {  short i;  below = 0;
  799.   for (i = 0; i <= ymax; i++)
  800.    memset((ptr)pxlmem[i], 0, (xmb+1)*sizeof(colpix));
  801. }
  802. static void pagebeg() {  uchar j;  greydesc *WITH;
  803.   for (j = 0; j <= 9; j++)  cnt[j] = dvinum(4);
  804.   lpp = dvinum(4);  pagnum++;
  805.   if (pagnum >= pag1) {  started = 1;  fprintf(prot, "[%d", pagnum);  }
  806.   s = 0;  w = 0;  x = 0;  y = 0;  z = 0;  zilli = 0;  lz = 0;  zoll = zoll0;
  807.   for (j = 0; j <= 7; j++) {  WITH = &greymask[j];  WITH->maskc = 0;
  808.     WITH->maskm = 0;  WITH->masky = 0;  WITH->maskk = 0xff;
  809.   }
  810.   zoelli = ftell(dvifile);  zoelli += (long)dvibufp - (long)dvibufe;
  811.   h = (long)((xres - hoff) / conv + 0.5);
  812.   v = (long)((yres - voff) / vconv + 0.5);
  813.   clrpxlmem();
  814. }
  815. static void pageend() {
  816.   if (s != 0)  fprintf(prot, "Stack not empty at EOP\n");
  817.   if (!started)  return;
  818.   hardcopy();  /* fprintf(prot, "/%d", (short)zoll); */
  819.   if (zoll > 0 && below) {  zoll--;  dviposit(zoelli);
  820.     s = 0;  w = 0;  x = 0;  y = 0;  z = 0;  zilli += ymax + 1;
  821.     h = (long)((xres - hoff) / conv + 0.5);
  822.     v = (long)((yres - voff) / vconv + 0.5);
  823.     clrpxlmem();  return;
  824.   }
  825.   hardform();  fprintf(prot, "]");
  826.   paganz--;  if (paganz <= 0) fini = 1;
  827. }
  828. static void deffont() {  ushort l, m;
  829.   if (!post) {  fontdef();  return;  }
  830.   dviskip(12L);  l = dvibyte();  m = dvibyte();  dviskip((long)(l + m));
  831. }
  832. static void special() {  long i, j, k;  char *parm;
  833.   double x, y, cy, ma, ye, bl;  short cle, m, n;
  834.   if (spl > 255) {  fprintf(prot, "special >>");
  835.     for (i = spl; i > 0; i--)  fputc(dvibyte(), prot);
  836.     fprintf(prot, "<< ignored\n");  return;
  837.   }
  838.   dvibytes(comment, (int)spl);
  839.   if (!memcmp(comment, "landend", 7)) {  dviori = 0;  return;  }
  840.   if (!memcmp(comment, "landstart", 9)) {
  841.     if (comment[10] == '1')  dviori = 1;
  842.     else if (comment[10] == '0')  dviori = 3;
  843.     else dviori = 2;
  844.     sscanf(comment+12, "%lg%lg", &x,&y);
  845.     j = (long)(x * 65535L + 0.5);
  846.     k = (long)(y * 65535L + 0.5);
  847.     switch (dviori) {
  848.     case 1:  landx = h - v;  landy = v + j + h;  break;
  849.     case 3:  landx = h + k + v;  landy = v - h;  break;
  850.     case 2:  landx = h + h + k;  landy = v + j + v;  break;
  851.   } return; }
  852.   if (memcmp(comment, "color", 5)) {
  853.     fprintf(prot, "special >>%s<< ignored", comment);  return;
  854.   }
  855.   parm = comment+6;
  856.   if (!memcmp(parm, "pop", 3)) {  parm +=4;  colst--;
  857.     if (colst < 0) {  colst = 0;  fprintf(prot, " color stack underflow"); }
  858.   } else {
  859.     if (!memcmp(parm, "push cmyk", 9)) {  parm +=10;  colst++;
  860.       if (colst > smax-1) { colst = smax-1;
  861.         fprintf(prot, " color stack overflow");
  862.     } }
  863.     if (sscanf(parm,"%lg%lg%lg%lg",&cy,&ma,&ye,&bl)<4) {
  864.       fprintf(prot," color: cmyk values <%s> incomplete ",comment); return;
  865.     }
  866.     n = (long)(cy * maxink);  if (n < 0) n = 0;
  867.     if (n > maxink) n = maxink;  stackcy[colst] = n;
  868.     n = (long)(ma * maxink);  if (n < 0) n = 0;
  869.     if (n > maxink) n = maxink;  stackma[colst] = n;
  870.     n = (long)(ye * maxink);  if (n < 0) n = 0;
  871.     if (n > maxink) n = maxink;  stackye[colst] = n;
  872.     n = (long)(bl * maxink);  if (n < 0) n = 0;
  873.     if (n > maxink) n = maxink;  stackbl[colst] = n;
  874.   }
  875.   n = stackcy[colst];  cle = n;
  876.   for (m = 0; m <= 7; m++)  greymask[m].maskc = maskb[n][0][m & 3];
  877.   n = stackma[colst];  cle += n;
  878.   for (m = 0; m <= 7; m++)  greymask[m].maskm = maskb[n][1][m & 3];
  879.   n = stackye[colst];  cle += n;
  880.   for (m = 0; m <= 7; m++)  greymask[m].masky = maskb[n][2][m & 3];
  881.   n = stackbl[colst];  cle += n;
  882.   for (m = 0; m <= 7; m++)  greymask[m].maskk = maskb[n][3][m & 3];
  883.   clearing = (cle == 0);
  884. }
  885. static void preambl() {  uchar l;
  886.   l = dvibyte();  num = dvinum(4);  den = dvinum(4);
  887.   dvimag = dvinum(4);  if (newmag != 0) dvimag = newmag;
  888.   conv = num / 254000.0 * ((double)xres / den) * (dvimag / 1000.0);
  889.   vconv = num / 254000.0 * ((double)yres / den) * (dvimag / 1000.0);
  890.   l = dvibyte();  dvibytes(comment, l);  fprintf(prot, "%s\n", comment);
  891. }
  892. static void postamb() {
  893.   lpp = dvinum(4);  num = dvinum(4);  den = dvinum(4);
  894.   dvimag = dvinum(4);  if (newmag != 0) dvimag = newmag;
  895.   conv = num / 254000.0 * ((double)xres / den) * (dvimag / 1000.0);
  896.   vconv = num / 254000.0 * ((double)yres / den) * (dvimag / 1000.0);
  897.   mxv = dvinum(4);  mxh = dvinum(4);  mst = dvinum(2);  mpn = dvinum(2);
  898. }
  899. main(int argc, char **argv) { char *parm;
  900.   post = 0;  fini = 0;  started = 0;  dviori = 0;  pagnum = 0;
  901.   pag1 = 1;  paganz = 9999;  newmag = 0;  q = 0;  hoff = 78;  voff = 156;
  902.   for (i = 0; i <= ymax; i++)  {
  903.     Tptr( pxlmem[i] = (colpix *) malloc((xmb+1)*sizeof(colpix)) );
  904.   }
  905.   Tptr( fontvect = (fontdesc **) calloc(256, 4) );
  906.   initbitrev();  colst = 0;
  907.   stackcy[colst] = 0;  stackma[colst] = 0;
  908.   stackye[colst] = 0;  stackbl[colst] = maxink;
  909.  
  910.   fprintf(prot, "This is the HP Deskjet 550 Color TeX driver, V 94.01 .\n");
  911.   fprintf(prot, "(C)opyright 1994 Wolfgang R. Mueller, Computing Centre,\n");
  912.   fprintf(prot, "Heinrich-Heine-University Duesseldorf, Germany\n");
  913.   if (argc == 1) {
  914.     fprintf(prot, "Please use with dvifilename and optional parameters\n");
  915.     fprintf(prot, " -s<starting page>     (default: 1  i.e. first in file)\n");
  916.     fprintf(prot, " -c<number of pages>   (default: 9999  i.e. all)\n");
  917.     fprintf(prot, " -m<new magnification> (default: from DVIfile)\n");
  918.     fprintf(prot, " -h<horizontal offset> (default: %ld (pixels)\n", hoff);
  919.     fprintf(prot, " -v<vertical offset>   (default: %ld (pixels)\n", voff);
  920.     fprintf(prot, " -f<font directory>    (default: %s)\n", fontprefix);
  921.     fprintf(prot, " -t<TFMfile directory> (default: %s)\n", tfmprefix);
  922.     fprintf(prot, " -o<outfile>           (default: %s)\n", prfnam);
  923.     fprintf(prot, "   prn for <outfile> goes directly to printer port,\n");
  924.     fprintf(prot, "   empty <outfile> part is replaced by <DVIfile>.pcl\n");
  925.     exit(0);
  926.   }
  927.   strcpy(dviname, "texput");
  928.   for (j = 1; j < argc; j++) {  parm = argv[j];
  929.     if (parm[0] != '-') {  strcpy(dviname, parm);
  930.     } else {  switch (parm[1]) {
  931.       case 's':  case 'S':  sscanf(parm+2, "%d", &pag1);  break;
  932.       case 'c':  case 'C':  sscanf(parm+2, "%d", &paganz);  break;
  933.       case 'f':  case 'F':  strcpy(fontprefix, parm+2);  break;
  934.       case 't':  case 'T':  strcpy(tfmprefix, parm+2);  break;
  935.       case 'm':  case 'M':  sscanf(parm+2, "%ld", &newmag);  break;
  936.       case 'h':  case 'H':  sscanf(parm+2, "%ld", &hoff);  break;
  937.       case 'v':  case 'V':  sscanf(parm+2, "%ld", &voff);  break;
  938.       case 'o':  case 'O':  strcpy(prfnam, parm+2);    break;
  939.   } } }
  940.   strcpy(defnam, dviname);  prfeval();  dviopen();  postamb();
  941.   do {  o = dvibyte();  /* fprintf(prot, "(%u)", (ushort)o); */
  942.     switch (o) {
  943.     case 128:  case 129:  case 130:  case 131:
  944.       c = dvinum(o - 127);  if (started) putchar_();  h += q;  break;
  945.     case 132:  a = dviint(4);  b = dviint(4);
  946.       if (started) putrule();  h += b;  break;
  947.     case 133:  case 134:  case 135:  case 136:
  948.       c = dvinum(o - 132);  if (started) putchar_();  break;
  949.     case 137:  a = dviint(4);  b = dviint(4);
  950.       if (started) putrule();  break;
  951.     case 138:  break;
  952.     case 139:  pagebeg();  break;
  953.     case 140:  pageend();  break;
  954.     case 141:  if (s < smax) {    s++;  hs[s - 1] = h;  vs[s - 1] = v;
  955.     ws[s - 1] = w;    xs[s - 1] = x;    ys[s - 1] = y; zs[s - 1] = z;
  956.       } else  baddvi("stack overflow");  break;
  957.     case 142:  if (s > 0) {  h = hs[s - 1];  v = vs[s - 1];
  958.     w = ws[s - 1];    x = xs[s - 1];    y = ys[s - 1];    z = zs[s - 1];    s--;
  959.       } else  baddvi("stack underflow");  break;
  960.     case 143:  case 144:  case 145:  case 146:
  961.       h += dviint(o - 142);  break;
  962.     case 147:  h += w;  break;
  963.     case 148:  case 149:  case 150:  case 151:
  964.       w = dviint(o - 147);  h += w;  break;
  965.     case 152:  h += x;  break;
  966.     case 153:  case 154:  case 155:  case 156:
  967.       x = dviint(o - 152);  h += x;  break;
  968.     case 157:  case 158:  case 159:  case 160:
  969.       v += dviint(o - 156);  break;
  970.     case 161:  v += y;  break;
  971.     case 162:  case 163:  case 164:  case 165:
  972.       y = dviint(o - 161);  v += y;  break;
  973.     case 166:  v += z;  break;
  974.     case 167:  case 168:  case 169:  case 170:
  975.       z = dviint(o - 166);  v += z;  break;
  976.     case 235:  case 236:  case 237:  case 238:
  977.       f = dvinum(o - 234);  if (started) fontset();  break;
  978.     case 239:  case 240:  case 241:  case 242:
  979.       spl = dvinum(o - 238);  special();  break;
  980.     case 243:  case 244:  case 245:  case 246:
  981.       f = dvinum(o - 242);  deffont();  break;
  982.     case 247:  preambl();  break;
  983.     case 248:  fini = 1;  break;
  984.     case 249:  dviposit(0L);  post = 1;  break;
  985.     case 250:  case 251:  case 252:
  986.     case 253:  case 254:  case 255:  break;
  987.     default:
  988.       if (o <= 127) {
  989.     c = o;    if (started) putchar_();  h += q;
  990.       } else if (o >= 171 && o <= 234) {
  991.     f = o - 171;  if (started)  fontset();
  992.   } break; } } while (!fini);
  993.   fprintf(prot,"\n"); prclos(); fclose(dvifile); exit(0);
  994. }
  995.